package com.thinkgem.jeesite.modules.data.rep.web;

import com.thinkgem.jeesite.common.utils.DateUtils;
import com.thinkgem.jeesite.modules.data.rep.entity.TfEcReportImgConf;
import org.activiti.engine.impl.util.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ui.Model;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by Havel on 2019/3/29/029.
 */
public class EchartDataConvertUtils {

    private static Logger logger = LoggerFactory.getLogger(EchartDataConvertUtils.class);

    /**
     * 适用条件：x轴是时间
     * 理解：maps可以没有数据，但是遍历必须严格按照时间走；该方法不行，因为遍历依赖maps数据
     * 兼容查询出来的数据 和 图形需要的数据一致情况，但效率较低
     * <p>
     * 场景：
     * 开始时间：
     * 传入时间 < 数据时间：没有数据的那部分时间显示为0，平均值降低（不准确）
     * 数据时间 < 传入时间：不影响数据，传入时间之外的数据时间的数据不会暂时，在这个方法里过滤
     * 结束时间：
     * @param model
     */
    public static void convertEchartDataXDate(TfEcReportImgConf imgConf, List<Map<String, Object>> maps, Model model) {
        if (imgConf == null)
            throw new RuntimeException("数据异常");

        //List<Map<String, Object>> newTest = new LinkedList<>();
        //for (int i = 0; i < maps.size(); i++) {
        //    Map<String, Object> newTestMap = new HashMap();
        //    //String d = DateUtils.timeStamp2Date(maps.get(i).get("CREATE_TIME").toString(),null);
        //    newTestMap.put("time", maps.get(i).get("CREATE_TIME").toString());
        //    newTestMap.put("cnt", maps.get(i).get("CNT"));
        //    newTest.add(newTestMap);
        //}
        //logger.info("==Havel=map=>" + JSONObject.toJSONString(newTest, SerializerFeature.WriteMapNullValue));

        List<TfEcReportImgConf> imgConfsResult = (List<TfEcReportImgConf>) model.asMap().get(TfEcReportImgConf.LIST_DATA_KEY);
        if (imgConfsResult == null) {
            imgConfsResult = new ArrayList<>();
        }

        Date beginDate = imgConf.getStartTime();
        Date endDate = imgConf.getEndTime();

        if (endDate == null) endDate = new Date();
        if (beginDate == null) {
            Calendar cal = Calendar.getInstance();
            cal.setTime(endDate);//要放在cal.add(Calendar.DAY_OF_MONTH, -30)之前
            cal.add(Calendar.DAY_OF_MONTH, -imgConf.getDataCnt()); //cond:最近30天的，时间间隔
            beginDate = cal.getTime();
        }

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");

        String begin = df.format(beginDate);
        String end = df.format(endDate);

        //x轴：开始时间到结束时间所经历的天数
        List<String> dates = new ArrayList();
        String tmpForDate = begin; //循环天数变量
        while (!tmpForDate.equals(end)) {
            dates.add("\"" + tmpForDate + "\"");
            Calendar calDay1 = Calendar.getInstance();
            calDay1.setTime(DateUtils.parseDate(tmpForDate));
            calDay1.add(Calendar.DATE, 1);
            tmpForDate = df.format(calDay1.getTime());
        }
        dates.add("\"" + tmpForDate + "\"");//最后一天
        //imgConfRes.setxAxisKey(imgConf.getxAxisKey()+imgConf.getImgConfId());
        //model.addAttribute("xDate_"+imgConf.getImgConfId(),dates);
        imgConf.setxAxisValues(dates);

        String forKey = "";
        String forDate = "";
        String thisTime = "";
        List<String> goodsIds = new ArrayList<>();
        Map<String, List<Integer>> goodsIdsData = new LinkedHashMap<>();
        List<Integer> values = new ArrayList<>();

        //== 需要配置的参数
        for (Map<String, Object> map1 : maps) {
            String tmpKey = map1.get(imgConf.getyAxisKey()).toString(); //y轴
            thisTime = df.format(map1.get(imgConf.getxAxisKey()));
            //初始化
            if (!tmpKey.equals(forKey)) { //新的goodsId
                if (!StringUtils.isEmpty(forKey)) {
                    goodsIdsData.put(forKey, values);
                }
                forKey = tmpKey; //== 新的goodsId
                goodsIds.add("\"" + tmpKey + "\"");
                values = new ArrayList<>();
                forDate = begin;
            }
            //循环的时间在数据时间之前，则循环的时间+1
            else if (DateUtils.parseDate(forDate).before(DateUtils.parseDate(thisTime))) {
                Calendar calDay1 = Calendar.getInstance();
                calDay1.setTime(DateUtils.parseDate(forDate));
                calDay1.add(Calendar.DATE, 1);
                forDate = df.format(calDay1.getTime());
            }
            //图形界面不要的数据就无需遍历：数据时间 < 遍历时间：forDate不动，thisTime遍历
            //else {
            //    continue;
            //}


            int cnt = Integer.parseInt(map1.get(imgConf.getDataKey()).toString());
            if (forDate.equals(thisTime)) { //是否这一天有数据
                values.add(cnt);//TODO
            } else if (!forDate.equals(end) && DateUtils.parseDate(forDate).before(DateUtils.parseDate(thisTime))) {
                //逐天碰撞,没碰撞到+1（数据时间 > 遍历时间，遍历时间+1碰撞，直到找到数据有数据的那一天，否则values中进0）
                while (!forDate.equals(end) && !forDate.equals(thisTime)) {
                    Calendar calDay1 = Calendar.getInstance();
                    calDay1.setTime(DateUtils.parseDate(forDate));
                    calDay1.add(Calendar.DATE, 1);
                    forDate = df.format(calDay1.getTime());
                    values.add(0);
                }
                values.add(cnt);
            }
            if (forDate.equals(end)) {
                goodsIdsData.put(forKey, values);
            }
        }
        if (goodsIdsData.size() != goodsIds.size()) {
            goodsIdsData.put(forKey, values);
        }
        //logger.info("==Havel=goodsIds=>" + JSONObject.toJSONString(goodsIds));
        //logger.info("==Havel=values=>" + JSONObject.toJSONString(values));
        //logger.info("==Havel=goodsIdsData=>" + JSONObject.toJSONString(goodsIdsData));

        //model.addAttribute(imgConf.getxAxisKey()+"_"+imgConf.getImgConfId(),);
        //model.addAttribute(imgConf.getDataKey()+"_"+imgConf.getImgConfId(),goodsIdsData);
        imgConf.setyAxisValues(goodsIds);
        imgConf.setDataValues(goodsIdsData);
        imgConfsResult.add(imgConf);
        model.addAttribute(TfEcReportImgConf.LIST_DATA_KEY, imgConfsResult);
    }

    /**
     * 标准条形图
     * data:['2011年'] //x
     * data : ['巴西','印尼','美国','印度','中国','世界人口(万)'] //y
     * series : [ //cnt
     * {
     * name:'2011年',
     * type:'bar',
     * data:[18203, 23489, 29034, 104970, 131744, 630230]
     * }]
     */
    public static void convertEchartDataTiao(TfEcReportImgConf imgConf, List<Map<String, Object>> maps, Model model) {
        //x轴取参数内容
        //y：goodsId
        //z：Map<goodsId,cnt>

        List<TfEcReportImgConf> imgConfsResult = (List<TfEcReportImgConf>) model.asMap().get(TfEcReportImgConf.LIST_DATA_KEY);
        if (imgConfsResult == null) {
            imgConfsResult = new ArrayList<>();
        }

        String forKey = "";
        List<String> xDate = new ArrayList<>(); //x
        List<String> yGoodsId = new ArrayList<>(); //y
        List<String> zValues = new ArrayList<>();//z
        Map<String, List<String>> goodsIdsData = new LinkedHashMap<>();

        //name: '2011年',
        //type: '',
        //data: [18203, 23489, 29034, 104970, 131744, 630230]
        for (Map<String, Object> map1 : maps) {
            String tmpKey = map1.get(imgConf.getxAxisKey()).toString();

            //String tmpKey = map1.get(imgConf.getyAxisKey()).toString(); //y轴 日期
            ////初始化
            if (!tmpKey.equals(forKey)) {
                if (!StringUtils.isEmpty(forKey)) {
                    goodsIdsData.put(forKey, zValues);
                }
                forKey = tmpKey;
                xDate.add("\"" + tmpKey + "\"");
                yGoodsId = new ArrayList<>();
            }
            String goodsId = map1.get(imgConf.getyAxisKey()).toString();
            yGoodsId.add("\"" + goodsId + "\"");
            zValues.add(map1.get(imgConf.getDataKey()).toString());
        }
        goodsIdsData.put(forKey, zValues);
        //logger.info("==Havel1=goodsIds=>" + JSONObject.toJSONString(xDate));
        //logger.info("==Havel1=values=>" + JSONObject.toJSONString(yGoodsId));
        //logger.info("==Havel1=goodsIdsData=>" + JSONObject.toJSONString(goodsIdsData));

        imgConf.setxAxisValues(xDate);
        imgConf.setyAxisValues(yGoodsId);
        imgConf.setDataValues(goodsIdsData);
        imgConfsResult.add(imgConf);
        model.addAttribute(TfEcReportImgConf.LIST_DATA_KEY, imgConfsResult);
    }

    /**
     * 标准条形图
     * legend: {
     * data:['巴西','印尼','美国','印度','中国']//x/y
     * },
     * yAxis : [{
     * type : 'category',
     * data : ['人口分布'] //标题
     * }],
     * series : [ //cnt
     * {
     * name:'巴西',
     * type:'bar',
     * data:[18203]
     * },
     * {
     * name:'印尼',
     * type:'bar',
     * data:[ 23489]
     * }, ……]
     * <p>
     * }]
     */
    public static void convertEchartDataTiao1(TfEcReportImgConf imgConf, List<Map<String, Object>> maps, Model model) {
        List<TfEcReportImgConf> imgConfsResult = (List<TfEcReportImgConf>) model.asMap().get(TfEcReportImgConf.LIST_DATA_KEY);
        if (imgConfsResult == null) {
            imgConfsResult = new ArrayList<>();
        }
        String forKey = "";
        List<String> goodsIds = new ArrayList<>();
        Map<String, List<String>> goodsIdsData = new LinkedHashMap<>();
        List<String> values = new ArrayList<>();

        for (Map<String, Object> map1 : maps) {
            String tmpKey = map1.get(imgConf.getyAxisKey()).toString(); //y轴
            //初始化
            if (!tmpKey.equals(forKey)) { //新的goodsId
                if (!StringUtils.isEmpty(forKey)) {
                    goodsIdsData.put(forKey, values);
                }
                forKey = tmpKey;
                goodsIds.add("\"" + tmpKey + "\"");
                values = new ArrayList<>();
            }
            values.add( map1.get(imgConf.getDataKey()).toString());
        }
        goodsIdsData.put(forKey,values);
        imgConf.setyAxisValues(goodsIds);
        imgConf.setDataValues(goodsIdsData);
        imgConfsResult.add(imgConf);
        model.addAttribute(TfEcReportImgConf.LIST_DATA_KEY, imgConfsResult);
    }


    /**
     * 两个月对比图：上个月和这个月
     * 注意事项：查询出来的数据必须是（即配置sql的时候必须对数据依据时间进行排序）
     */
    //参考：https://echarts.baidu.com/examples/editor.html?c=multiple-x-axis
    //option = {
    //    color: colors,
    //    legend: {
    //        data:['2015 降水量', '2016 降水量'] //y轴
    //    },
    //    grid: {
    //        top: 70,
    //                bottom: 50
    //    },
    //    xAxis: [ //x轴
    //    {
    //        type: 'category',
    //        data: ["2016-1", "2016-2", "2016-3", "2016-4", "2016-5", "2016-6", "2016-7", "2016-8", "2016-9", "2016-10", "2016-11", "2016-12"]
    //    },
    //    {
    //        type: 'category',
    //        data: ["2015-1", "2015-2", "2015-3", "2015-4", "2015-5", "2015-6", "2015-7", "2015-8", "2015-9", "2015-10", "2015-11", "2015-12"]
    //    }
    //],
    //    yAxis: [
    //    {
    //        type: 'value'
    //    }
    //],
    //    series: [ //data
    //    {
    //        name:'2015 降水量',
    //        type:'line',
    //        xAxisIndex: 1,
    //        smooth: true,
    //        data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3]
    //    },
    //    {
    //        name:'2016 降水量',
    //        type:'line',
    //        smooth: true,
    //        data: [3.9, 5.9, 11.1, 18.7, 48.3] //这个数据和上面数据对比不一定要数据量相等
    //    }
    //]
    //};
    //===>
    //y轴data：['2015 降水量', '2016 降水量']
    //x轴：data: ["2015-1", "2015-2", "2015-3", "2015-4", "2015-5", "2015-6", "2015-7", "2015-8", "2015-9", "2015-10", "2015-11", "2015-12"]
    //data：[2015 降水量]{data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3]}
    public static void convertEchartTwoMonthCompare(TfEcReportImgConf imgConf, List<Map<String, Object>> maps, Model model) {
        List<TfEcReportImgConf> imgConfsResult = (List<TfEcReportImgConf>) model.asMap().get(TfEcReportImgConf.LIST_DATA_KEY);
        if (imgConfsResult == null) {
            imgConfsResult = new ArrayList<>();
        }
        String forKey = "";
        List<String> goodsIds = new ArrayList<>();
        Map<String, List<String>> valuesData = new LinkedHashMap<>();//data
        List<String> values = new ArrayList<>();//data-value
        Map<String,List<String>> xValuseData = new LinkedHashMap<>();//x
        List<String> xValues = new ArrayList<>();//x-values

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        //获取当前月第一天：
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, -1);
        //c.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期即为本月第一天
        String preMonth = format.format(c.getTime());//当月第一天

        String flag = "pre";
        String endDate = "";

        for (Map<String, Object> map1 : maps) {
            //String tmpKey = map1.get(imgConf.getyAxisKey()).toString(); //y轴：降水量
            //初始化
            //if (!tmpKey.equals(forKey)) { //新的goodsId
            //    if (!StringUtils.isEmpty(forKey)) {
            //        goodsIdsData.put(forKey, values);
            //    }
            //    forKey = tmpKey;
            //    goodsIds.add("\"" + tmpKey + "\"");
            //    values = new ArrayList<>();
            //}
            String thisMonth = format.format(map1.get(imgConf.getxAxisKey()));

            if(thisMonth.equals(preMonth)){
                xValues.add( "\"" +map1.get(imgConf.getxAxisKey()).toString().substring(5,10)+"\"");//添加日期
                values.add(map1.get(imgConf.getDataKey()).toString());//添加数据
            }else if("pre".equals(flag)){
                //将上个月的放进来
                flag = "this";
                xValuseData.put("上月量",xValues);
                valuesData.put("上月量",values);
                xValues = new ArrayList<>();//x-values
                values = new ArrayList<>();//data-value
                xValues.add( "\"" +map1.get(imgConf.getxAxisKey()).toString().substring(5,10)+"\"");//添加日期
                values.add(map1.get(imgConf.getDataKey()).toString());//添加数据
            }else{
                xValues.add( "\"" +map1.get(imgConf.getxAxisKey()).toString().substring(5,10)+"\"");//添加日期
                values.add(map1.get(imgConf.getDataKey()).toString());//添加数据
                endDate = map1.get(imgConf.getxAxisKey()).toString();
            }
            //values.add(map1.get(imgConf.getDataKey()).toString());
        }


        //获取当前月第一天
        endDate = endDate.substring(0,10);
        Calendar ca = Calendar.getInstance();
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        format = new SimpleDateFormat("yyyy-MM-dd");
        String last = format.format(ca.getTime());

        //日期补全
        String forDate = endDate;
        //if(!DateUtils.parseDate(endDate).before(DateUtils.parseDate(last))) {
        while (DateUtils.parseDate(forDate).before(DateUtils.parseDate(last))||!(DateUtils.parseDate(forDate).getTime() == DateUtils.parseDate(last).getTime())) {
            Calendar calDay1 = Calendar.getInstance();
            calDay1.setTime(DateUtils.parseDate(forDate));
            calDay1.add(Calendar.DATE, 1);
            forDate = format.format(calDay1.getTime());
            xValues.add( "\"" +forDate.substring(5,10)+"\"");//添加日期
        }
        //}
        xValuseData.put("当月量",xValues);
        valuesData.put("当月量",values);

        imgConf.setxAxisValuesEx(xValuseData);
        imgConf.setDataValues(valuesData);

        //logger.info("==Havel1=xValuseData=>" + JSONObject.toJSONString(xValuseData));
        //logger.info("==Havel1=valuesData=>" + JSONObject.toJSONString(valuesData));

        imgConfsResult.add(imgConf);
        //logger.info("==Havel==>" + JSONObject.toJSONString(imgConf, SerializerFeature.WriteMapNullValue));
        model.addAttribute(TfEcReportImgConf.LIST_DATA_KEY, imgConfsResult);
    }

}
